package com.study.seata.storage.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.seata.tm.api.GlobalTransactionContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import com.study.seata.common.constant.SeataConstant;

import io.seata.core.context.RootContext;

/**
 * Http Rest请求拦截器，用于把当前上下文中获取到的XID放到RootContext
 * @author
 */
@Slf4j
public class SeataXidFilter extends OncePerRequestFilter {


	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		final String xid = RootContext.getXID();
		final String restXid = request.getHeader(SeataConstant.XID_HEADER);
		final String xidTmp = GlobalTransactionContext.getCurrentOrCreate().getXid();
		System.out.println("xid="+xid+",restXid="+restXid+",xidTmp="+xidTmp);
		boolean bind = false;
		if (StringUtils.isBlank(xid) && StringUtils.isNotBlank(restXid)) {
			RootContext.bind(restXid);
			bind = true;
			log.debug("bind[" + restXid + "] to RootContext");
		}
		try {
			filterChain.doFilter(request, response);
		} finally {
			if (bind) {
				String unbindXid = RootContext.unbind();
				log.debug("unbind[" + unbindXid + "] from RootContext");
				if (!restXid.equalsIgnoreCase(unbindXid)) {
					log.warn("xid in change during http rest from " + restXid + " to " + unbindXid);
					if (unbindXid != null) {
						RootContext.bind(unbindXid);
						log.warn("bind [" + unbindXid + "] back to RootContext");
					}
				}
			}
		}
		return;
	}

}
